﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>//io流标准输入输出头文件，没有.h，老一点的版本才有
#if 0
using namespace std//对standard库展开
int main()
{
	int a = 0;
	scanf("%d", &a);
	printf("%d", a);//C++兼容C
	//但是C++有自己的一套输出输入
	cin >> a;//输入
	cout << a << endl;//输出
}
#endif // 0

//C++有自己的命名空间使用，namespace+空间名+{}

//他为什么会有自己记的命名空间呢？主要是针对C语言一些头文件展开后存在命名冲突的问题
//比如

//rand 是个函数这样命名就会出错；所以C++专门搞了一个命名空间域；
//命名空间域里可以是类型，函数，结构体等；
//命名空间域只能全局，可以嵌套定义

namespace jxm
{
	int rand = 0;
	int a = 20;
	int b = 21;
}
using jxm::b;
using namespace jxm;//也可以对整个域名展开；但这样就有一定的风险;张开后相当于收回了那一层保护伞；还是会存在命名冲突的问题
using namespace std;
//int rand = 0;
//多个同样的域名，不会冲多，

int main1()
{
	//std::cout << rand <<std:: endl;
	printf("%d", jxm::rand);//对命名域内指定变量访问 域名::变量名
	cout << b << endl;//对b展开后就不用像上面那样写了
	return 0;
}


int main2()
{
	int a = 1;
	double b = 0.2;
	char c = 'c';
	//C++标准输入输出流他会自己确定类型，不需要自己指定；
	cin >> a;
	//输入可以单个写，也可以多个写
	cin >> b >> c;
	cout << a << " " << b << " " << c << endl;//输出的格式是将所有的东西转换成字符以后进行输出；
	//空格不能跟在a后面，因为cout是一个函数传参的时候只能传一个
	// c++输出流控制小数点后几位有点写，不过C++兼容C，只写写C的那一套就可以；
	return 0;
}


//函数缺省参数（默认值）

int Add(int a = 10, int b = 30)
{
	return a + b;
}

int main3()
{
	int c = Add();//不创参就默认为是上面的缺省参数；如果传参，缺省参数失效；所以做人不要做缺省参数；
	cout << c << endl;
	return 0;
}

//缺省参数的一些规则
//1.缺省分为全缺省和半缺省；
//全缺省就是所有参数都给默认值；
//半缺省：有些给默认值，有些不给默认是，给默认值必须从右边给，中间还不能跳槽；
//带缺省值的函数传参的时候必须从左往右，中间不能跳跃,可以只传不是缺省的那
//声明和定义分离时，缺省不能在声明和定义中同时出现缺省必须在声明函数的时候给缺省值；
int sij(int a, int b = 42, int c = 30)
{
	return a + b - c;
}

int main4()
{
	int d = sij(10);
	cout << d << endl;
	return 0;
}

//函数重载：函数名一样，但函数参数类型，个数，类型顺序等，不同

//类型不同
void Add1(int a, int b)
{
	cout << "Add1(int a,int b)" << endl;
}

void Add1(double a, double b)
{
	cout << "Add1(double a,double b" << endl;
}

//顺序不同
void Add2(int a, char c)
{
	cout << "Add2<int a,char c)" << endl;
}

void Add2(char c, int a)
{
	cout << "Add2(char c,int a)" << endl;
}

//参数个数不同
void Add3()
{
	cout << "Add3()" << endl;
}

void Add3(int a)
{
	cout << "Add3(int a)" << endl;
}
void f()
{
	cout << "f()" << endl;
}
namespace jxm 
{
	void f(int a = 0)
	{
		cout << "f(int a = 0)" << endl;
	}
}
//对于这种缺省的函数，就不能和同名没有参数的函数写在同一作用了；因为缺省函数不传参也能使用；
// 所以当两个都同时存在的时候，编译器就不知道使用谁了；这时候可以用域名来把一个放进去，把他们两个隔开
using  jxm::f;

int main5()
{
	Add1(1, 2);
	Add1(0.1, 0.2);
	Add2(1, 'c');
	Add2('c', 1);
	Add3();
	Add3(1);
	jxm::f();
	return 0;
}

//引用：类型& 引⽤别名 = 引⽤对象
//引用不是定义新的变量，而是给已有的变量取别名；引用不会开辟额外的空间，而是和这个变量用同一块空间；
//引用的时候必须给初始值；
//这个引用一旦引用了实体就不能引用其他实体

int main6()
{
	int a = 0;
	int c = 1;
	//int& b;//引用必须给初始值，因为他是对已有的东西区别名
	int& b = a;
	
	cout << ++b << endl;
	return 0;
}

//引用就相当于，你是我，我是你；
//引用有指针的功能，但不能代替指针；
//在传参的时候很好用；可以用不用传地址，用指针接收，可以用引用

void Swap(int& c, int& d)
{
	int tmp = c;
	c = d;
	d = tmp;
}

int main()
{
	int a = 10;
	int b = 20;
	Swap(a, b);
	cout << a << " " << b << endl;
}
//就是因为地址相同所以他才能做到这样的功能
//总之在传参的时候就是很好用；